/**
 * 定义porlet
 */
Ext.ux.Portlet = Ext.extend(Ext.Panel, {
	anchor : '100%',
	frame : true,
	collapsible : true,
	draggable : true,
	cls : 'x-portlet'
});
Ext.reg('portlet', Ext.ux.Portlet);
/**
 * 定义 portalcolumn
 */
Ext.ux.PortalColumn = Ext.extend(Ext.Container, {
	layout : 'anchor',
	autoEl : 'div',
	defaultType : 'portlet',
	cls : 'x-portal-column'
});
Ext.reg('portalcolumn', Ext.ux.PortalColumn);

/**
 * 定义portal
 */
Ext.ux.Portal = Ext.extend(Ext.Panel, {
	layout : 'column',
	autoScroll : true,
	cls : 'x-portal',
	defaultType : 'portalcolumn',
	initComponent : function() {
		Ext.ux.Portal.superclass.initComponent.call(this);
		this.addEvents({
			validatedrop : true,
			beforedragover : true,
			dragover : true,
			beforedrop : true,
			drop : true
		});
	},

	initEvents : function() {
		Ext.ux.Portal.superclass.initEvents.call(this);
		this.dd = new Ext.ux.Portal.DropZone(this, this.dropConfig);
	}
});
Ext.reg('portal', Ext.ux.Portal);

Ext.ux.Portal.DropZone = function(portal, cfg) {
	this.portal = portal;
	Ext.dd.ScrollManager.register(portal.body);
	Ext.ux.Portal.DropZone.superclass.constructor.call(this, portal.bwrap.dom,
			cfg);
	portal.body.ddScrollConfig = this.ddScrollConfig;
};

Ext.extend(Ext.ux.Portal.DropZone, Ext.dd.DropTarget, {
	ddScrollConfig : {
		vthresh : 50,
		hthresh : -1,
		animate : true,
		increment : 200
	},

	createEvent : function(dd, e, data, col, c, pos) {
		return {
			portal : this.portal,
			panel : data.panel,
			columnIndex : col,
			column : c,
			position : pos,
			data : data,
			source : dd,
			rawEvent : e,
			status : this.dropAllowed
		};
	},

	notifyOver : function(dd, e, data) {
		var xy = e.getXY(), portal = this.portal, px = dd.proxy;
		// case column widths
		if (!this.grid) {
			this.grid = this.getGrid();
		}
		// handle case scroll where scrollbars appear during drag
		var cw = portal.body.dom.clientWidth;
		if (!this.lastCW) {
			this.lastCW = cw;
		} else if (this.lastCW != cw) {
			this.lastCW = cw;
			portal.doLayout();
			this.grid = this.getGrid();
		}

		// determine column
		var col = 0, xs = this.grid.columnX, cmatch = false;
		for (var len = xs.length; col < len; col++) {
			if (xy[0] < (xs[col].x + xs[col].w)) {
				cmatch = true;
				break;
			}
		}
		// no match, fix last index
		if (!cmatch) {
			col--;
		}

		// find insert position
		var p, match = false, pos = 0, c = portal.items.itemAt(col), items = c.items.items;

		for (var len = items.length; pos < len; pos++) {
			p = items[pos];
			var h = p.el.getHeight();
			if (h !== 0 && (p.el.getY() + (h / 2)) > xy[1]) {
				match = true;
				break;
			}
		}

		var overEvent = this.createEvent(dd, e, data, col, c, match && p
				? pos
				: c.items.getCount());

		if (portal.fireEvent('validatedrop', overEvent) !== false
				&& portal.fireEvent('beforedragover', overEvent) !== false) {
			// make sure proxy width is fluid
			px.getProxy().setWidth('auto');

			if (p) {
				px.moveProxy(p.el.dom.parentNode, match ? p.el.dom : null);
			} else {
				px.moveProxy(c.el.dom, null);
			}

			this.lastPos = {
				c : c,
				col : col,
				p : match && p ? pos : false
			};
			this.scrollPos = portal.body.getScroll();

			portal.fireEvent('dragover', overEvent);
			return overEvent.status;
		} else {
			return overEvent.status;
		}

	},

	notifyOut : function() {
		delete this.grid;
	},

	notifyDrop : function(dd, e, data) {
		delete this.grid;
		if (!this.lastPos) {
			return;
		}
		var c = this.lastPos.c, col = this.lastPos.col, pos = this.lastPos.p;
		// 目标portalColumn id: c.id
		// 当前被拖动portlet的信息 alert(dd.panel.id+':'+dd.panel.title);
		var dropEvent = this.createEvent(dd, e, data, col, c, pos !== false
				? pos
				: c.items.getCount());
		if (this.portal.fireEvent('validatedrop', dropEvent) !== false
				&& this.portal.fireEvent('beforedrop', dropEvent) !== false) {

			dd.proxy.getProxy().remove();
			dd.panel.el.dom.parentNode.removeChild(dd.panel.el.dom);
			if (pos !== false) {
				c.insert(pos, dd.panel);
			} else {
				c.add(dd.panel);
			}
			/**
			 * 取得当前portlet在portal column中的索引
			 */
			var index = 0;
			var portletId = dd.panel.id;
			if (pos != false) {
				var portlets = c.items;
				for (var i = 0; i < portlets.length; i++) {
					if (c.items.itemAt(i).id === portletId) {
						index = i;
						break;
					}
				}
			} else {
				if (pos.toString() == '0') {
					index = 0;
				} else {
					index = c.items.length - 1;
				}
			}
			c.doLayout();
			Ext.Ajax.request({
				url : BP+'portalContainerAction.do?method=movePortlet',
				params : {
					portalId : this.portal.id,
					portletId : dd.panel.id.split('_')[0],
					portalColumnId : c.id,
					index : index
				}
			});
			this.portal.fireEvent('drop', dropEvent);

			// scroll position is lost on drop, fix it
			var st = this.scrollPos.top;
			if (st) {
				var d = this.portal.body.dom;
				setTimeout(function() {
					d.scrollTop = st;
				}, 10);
			}

		}
		delete this.lastPos;
	},

	// internal cache of body and column coords
	getGrid : function() {
		var box = this.portal.bwrap.getBox();
		box.columnX = [];
		this.portal.items.each(function(c) {
			box.columnX.push({
				x : c.el.getX(),
				w : c.el.getWidth()
			});
		});
		return box;
	}
});